//-----------------------------------------------------------------------------
// Torque Game Engine 
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------

// This file contains Weapon and Ammo Class/"namespace" helper methods
// as well as hooks into the inventory system. These functions are not
// attached to a specific C++ class or datablock, but define a set of
// methods which are part of dynamic namespaces "class". The Items
// include these namespaces into their scope using the  ItemData and
// ItemImageData "className" variable.

// All ShapeBase images are mounted into one of 8 slots on a shape.
// This weapon system assumes all primary weapons are mounted into
// this specified slot:
$WeaponSlot = 0;

$weaponInSlot[0] = "RocketPistol";
$weaponInSlot[1] = "GrenadeLauncher";
$weaponInSlot[2] = "RocketLauncher";
$weaponInSlot[3] = "mac10";

$maxWeaponSlot = 3;


//-----------------------------------------------------------------------------
// Audio profiles

datablock AudioProfile(WeaponUseSound)
{
	filename = "~/data/sound/weapon_switch.wav";
	description = AudioClose3d;
	preload = true;
};

datablock AudioProfile(WeaponPickupSound)
{
	filename = "~/data/sound/weapon_pickup.wav";
	description = AudioClose3d;
	preload = true;
};

datablock AudioProfile(AmmoPickupSound)
{
	filename = "~/data/sound/ammo_mono_01.ogg";
	description = AudioClose3d;
	preload = true;
};


//-----------------------------------------------------------------------------
// Weapon Class 
//-----------------------------------------------------------------------------

function Weapon::onUse(%data,%obj)
{
	// Default behavoir for all weapons is to mount it into the
	// this object's weapon slot, which is currently assumed
	// to be slot 0
	if (%obj.getMountedImage($WeaponSlot) != %data.image.getId()) {
		serverPlay3D(WeaponUseSound,%obj.getTransform());
		%obj.mountImage(%data.image, $WeaponSlot);
		if (%obj.client)
			messageClient(%obj.client, 'MsgWeaponUsed', '\c0Weapon selected');
	}
}

function Weapon::onPickup(%this, %obj, %shape, %amount)
{
	// The parent Item method performs the actual pickup.
	// For player's we automatically use the weapon if the
	// player does not already have one in hand.
	if (Parent::onPickup(%this, %obj, %shape, %amount)) {
		serverPlay3D(WeaponPickupSound,%obj.getTransform());
		if (%shape.getClassName() $= "Player" && 
			%shape.getMountedImage($WeaponSlot) == 0)  {
			%shape.use(%this);
		}
	}
}

function Weapon::onInventory(%this,%obj,%amount)
{
	// Weapon inventory has changed, make sure there are no weapons
	// of this type mounted if there are none left in inventory.
	if (!%amount && (%slot = %obj.getMountSlot(%this.image)) != -1)
		%obj.unmountImage(%slot);
}   


//-----------------------------------------------------------------------------
// Weapon Image Class
//-----------------------------------------------------------------------------

function WeaponImage::onMount(%this,%obj,%slot)
{
   // Images assume a false ammo state on load.  We need to
   // set the state according to the current inventory.
   if (%obj.getInventory(%this.ammo))
      %obj.setImageAmmo(%slot,true);
}


//-----------------------------------------------------------------------------
// Ammmo Class
//-----------------------------------------------------------------------------

function Ammo::onPickup(%this, %obj, %shape, %amount)
{
   // The parent Item method performs the actual pickup.
   if (Parent::onPickup(%this, %obj, %shape, %amount)) {
      serverPlay3D(AmmoPickupSound,%obj.getTransform());
   }
}

function Ammo::onInventory(%this,%obj,%amount)
{
   // The ammo inventory state has changed, we need to update any
   // mounted images using this ammo to reflect the new state.
   for (%i = 0; %i < 8; %i++) {
      if ((%image = %obj.getMountedImage(%i)) > 0)
         if (isObject(%image.ammo) && %image.ammo.getId() == %this.getId())
            %obj.setImageAmmo(%i,%amount != 0);
   }
}






// Listen for server command to cycle a client player's weapon
function serverCmdCycleWeapon( %client, %data )
{
	%client.getControlObject().cycleWeapon( %data );
}

// Cycles to the next weapon in a players inventory
function ShapeBase::cycleWeapon( %this, %data )
{
	// Find out which slot we're currently in
	%slot = -1;
	if ( %this.getMountedImage($WeaponSlot) != 0 )
	{
		%curWeapon = %this.getMountedImage($WeaponSlot).item.getName();
		if(%curWeapon $= "RocketPistol")
			%slot = 0;
		else if(%curWeapon $= "GrenadeLauncher")
			%slot = 1;
		else if(%curWeapon $= "RocketLauncher")
			%slot = 2;
		else if(%curWeapon $= "mac10")
			%slot = 3;
	}
	// Cycle backwards
	if ( %data $= "prev" )
	{
		if ( %slot == 0 || %slot == -1 )
		{
			%i = $maxWeaponSlot;
			%slot = 0;
		}
		else
			%i = %slot - 1;
	}
	// Cycle forward
	else
	{
		if ( %slot == $maxWeaponSlot || %slot == -1 )
		{
			%i = 0;
			%slot = $maxWeaponSlot;
		}
		else
			%i = %slot + 1;
   }
	%newSlot = -1;
	while ( %i != %slot )   
	{
		if ( $weaponInSlot[%i] !$= "" && %this.hasInventory( $weaponInSlot[%i] ))
		{
			// player has this weapon and it has ammo or doesn't need ammo
			%newSlot = %i;
			break;
		}
		if ( %data $= "prev" )
		{
			if ( %i == 0 )
				%i = $maxWeaponSlot;
			else
				%i--;
		}
		else
		{
			if ( %i == $maxWeaponSlot )
				%i = 0;
			else
				%i++;
		}
	}
	if ( %newSlot != -1 )
	%this.use( $weaponInSlot[%newSlot] );
}
